package com.android.basiclib.utils

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.os.Handler
import android.os.HandlerThread
import android.view.ViewPropertyAnimator
import androidx.lifecycle.*
import com.android.basiclib.utils.log.MyLogUtils

/**
 * 异步动画工具类
 */
class AsyncAnimUtil private constructor() : DefaultLifecycleObserver {

    private var mHandlerThread: HandlerThread? = HandlerThread("anim_run_in_thread")

    private var mHandler: Handler? = mHandlerThread?.run {
        start()
        Handler(this.looper)
    }

    private var mOwner: LifecycleOwner? = null
    private var mAnim: ViewPropertyAnimator? = null
    private var mValueAnimator: ValueAnimator? = null

    companion object {
        val instance: AsyncAnimUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            AsyncAnimUtil()
        }
    }

    //启动View的属性动画
    fun startAnim(owner: LifecycleOwner?, animator: ViewPropertyAnimator) {
        try {
            if (mOwner != owner) {
                mOwner = owner
                addLoopLifecycleObserver()
            }

            if (mHandlerThread?.isAlive != true) {
                MyLogUtils.w("handlerThread restart")
                mHandlerThread = HandlerThread("anim_run_in_thread")
                mHandler = mHandlerThread?.run {
                    start()
                    Handler(this.looper)
                }
            }

            mHandler?.post {
                mAnim = animator.setListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationEnd(animation: Animator) {
                        super.onAnimationEnd(animation)
                        destroy()
                    }

                    override fun onAnimationCancel(animation: Animator) {
                        super.onAnimationCancel(animation)
                        destroy()
                    }

                    override fun onAnimationEnd(animation: Animator, isReverse: Boolean) {
                        super.onAnimationEnd(animation, isReverse)
                        destroy()
                    }
                })
                mAnim?.start()
            }

        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    //启动值的属性动画
    fun startAnim(owner: LifecycleOwner?, animator: ValueAnimator, isInThread: Boolean = true) {
        try {
            if (mOwner != owner) {
                mOwner = owner
                addLoopLifecycleObserver()
            }

            mValueAnimator = animator

            if (isInThread) {
                if (mHandlerThread?.isAlive != true) {
                    MyLogUtils.w("handlerThread restart")
                    mHandlerThread = HandlerThread("anim_run_in_thread")
                    mHandler = mHandlerThread?.run {
                        start()
                        Handler(this.looper)
                    }
                }

                mHandler?.post {

                    startValueAnim()
                }
            } else {
                //如果不在线程中，直接启动即可
                startValueAnim()
            }

        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    private fun startValueAnim() {

        mValueAnimator?.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(p0: Animator) {
            }

            override fun onAnimationEnd(p0: Animator) {
                destroy()
            }

            override fun onAnimationCancel(p0: Animator) {
                destroy()
            }

            override fun onAnimationRepeat(p0: Animator) {
            }
        })
        mValueAnimator?.start()
    }

    // 绑定当前页面生命周期
    private fun addLoopLifecycleObserver() {
        mOwner?.lifecycle?.addObserver(this)
    }

    override fun onDestroy(owner: LifecycleOwner) {
        mAnim?.cancel()
        mValueAnimator?.cancel()
        destroy()
    }

    private fun destroy() {
        try {
            mHandlerThread?.quitSafely()

            mAnim = null
            mValueAnimator = null
            mOwner = null
            mHandler = null
            mHandlerThread = null
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

}